#include <bits/stdc++.h>
#include <thread>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

using namespace std;

//string testFile = "data/test_data1.txt";
string testFile = "data/test_data2.txt";//30000 node,1004812
//string testFile = "data/test_data3.txt";//25700 node,2896262

string resultFile = "reslt.txt";

int node_num = 0;
typedef uint account;

account nodes[2*280000];
unordered_map<account, int> idHash;
int G[280000][50];
int len[280000];


inline unsigned int parse(char** s){
	char *p = *s;
	unsigned int val = *(p++) - '0';
	while(*p != ','){
		val = 10*val + *(p++) - '0';
	}
	*s = p+1;
	return val;
}
void loadData_and_createGrap(){
	int fd = open(testFile.c_str(), O_RDONLY);
    int file_size = lseek(fd, 0, SEEK_END);
    char* p_map =(char*)mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
    close(fd);
	char *p = p_map;
	account inputs[2*280000], n=0;
	while(*p != '\0'){
		inputs[n++]=(parse(&p));
		inputs[n++]=(parse(&p));
		while(*p != '\n') p++;
		p++;
	}
	memcpy(nodes,inputs,4*2*280000);
	sort(nodes,nodes+2*280000);//排序
	node_num = unique(nodes,nodes+2*280000) - nodes;//去重
	for(int i=0; i<node_num; i++){idHash[nodes[i]] = i;len[i]=0;}
	for(int i=0,a=0; i<n; i+=2){a=idHash[inputs[i]];G[a][len[a]++]=idHash[inputs[i+1]];}
	for(int i=0; i<node_num; i++) sort(G[i],G[i]+len[i]);
	munmap(p_map, file_size);
}


int ans3[3*500000];
int ans4[4*500000];
int ans5[5*1000000];
int ans6[6*2000000];
int ans7[7*3000000];
int *ans[]={ans3, ans4, ans5, ans6, ans7};
int p[5] = {0, 0, 0, 0, 0};
vector<bool> vis;

int path[7];
void dfs(int head,int cur,int depth){
	vis[cur]=true;
	path[depth-1]=cur;
	for(int i=0,v=G[cur][0]; i<len[cur]; v=G[cur][++i]){
		if(v==head && depth>=3 && depth<=7){
			memcpy(ans[depth-3]+p[depth-3], path, 4*depth);
			p[depth-3] += depth;
		}
		if(depth<7 && !vis[v] && v>head){
			dfs(head,v,depth+1);
		}
	}
	vis[cur]=false;
}

void solve(){
	vis=vector<bool>(node_num,false);
	for(int i=0;i<node_num;i++){
		if(len[i]!=0){
			dfs(i,i,1);
		}
	}
	//sort(ans.begin(),ans.end());
	cout<<"ans.size = "<<p[0]/3 + p[1]/4 + p[2]/5 + p[3]/6 + p[4]/7<<endl;
}

int main(int argc, char* argv[]){
	
	clock_t startTime = clock();
	loadData_and_createGrap();
	clock_t endTime = clock();
	cout << "LoadData: " << (float)(endTime - startTime) / CLOCKS_PER_SEC << " s" << endl;
	
	startTime = clock();
	
	solve();
	
	endTime = clock();
	cout << "compute: " << (float)(endTime - startTime) / CLOCKS_PER_SEC << " s" << endl;
	
	
	return 0;
}